import { useState, useEffect } from "preact/hooks";
import { move, equals, dropLastWhile } from "ramda";
import { setFileName } from "./Vendor";
import { toast } from "./signals";

export function downText(text, name) {
  if (text.length > 0) {
    const a = document.createElement("a");
    a.href = URL.createObjectURL(new Blob([text]));
    a.download = name;
    Object.assign(a.style, {
      position: "fixed",
      top: "200%",
    });
    document.body.append(a);
    setTimeout(() => {
      a.click();
      setFileName(name, a.href);
      a.remove();
    });
  } else toast("内容为空");
}

async function openFile() {
  try {
    const [handle] = await globalThis.showOpenFilePicker({ multiple: false });
    const file = await handle.getFile();
    const content = await file.text();
    return JSON.parse(content);
  } catch {
    toast("打开失败");
  }
}

export function importData(failTester, importer) {
  const merge = confirm("选择确定合并数据，选择取消覆盖数据");
  openFile()
    .then((data) => {
      if (failTester(data)) return toast("导入数据有误或被取消");
      importer(data, merge);
    })
    .catch(() => toast("导入失败"));
}

export function copyText(text) {
  navigator.clipboard
    .writeText(text)
    .then(() => {
      toast("复制成功");
    })
    .catch(() => toast("复制失败"));
}

export function useThrottle(defaultValue, delay) {
  const [value, setValue] = useState(defaultValue);
  let id = -1;
  const throttleSetter = (v) => {
    if (id === -1) {
      setValue(v);
      id = setTimeout(() => {
        id = -1;
      }, delay);
    }
  };
  useEffect(() => () => clearTimeout(id), [id]);
  return [value, throttleSetter];
}

export function useLogoVisible(engBarReference) {
  const [visible, setVisible] = useState(true);
  useEffect(() => {
    const observer = new IntersectionObserver((ioes) => {
      for (const ioe of ioes) {
        setVisible(ioe.isIntersecting);
      }
    });
    if (engBarReference.current) {
      observer.observe(engBarReference.current);
    }
    return () => observer.disconnect();
  }, [engBarReference]);
  return visible;
}

export const stopPropagation = (event) => event.stopPropagation();

export function checkImage(source) {
  return new Promise((resv, rej) => {
    const img = new Image(0, 0);
    img.src = source;
    img.addEventListener("load", () => {
      img.remove();
      resv(source);
    });
    img.addEventListener("error", () => {
      img.remove();
      rej(source);
    });
    document.body.append(img);
  });
}

export function getIndex(current, one, property = void 0) {
  return current.findIndex(
    (item) => (property ? item[property] : item) === one,
  );
}

export function turn(current, up, min, max) {
  const updated = current + (up ? -1 : 1);
  if (updated > max) {
    return min;
  } else if (updated < min) {
    return max;
  } else return updated;
}

export function moveItem(current, item, up, property = void 0) {
  const index = getIndex(current, item, property);
  const indexAfter = turn(index, up, 0, current.length - 1);
  return move(index, indexAfter, current);
}

export function checkKey(object, keys, remove = "") {
  return equals(
    dropLastWhile((x) => x === remove, Object.keys(object)),
    keys,
  );
}

export function isStarts(long, short, checkCase = false) {
  return checkCase
    ? long.startsWith(short)
    : long.toLowerCase().startsWith(short.toLowerCase());
}

const numberFormatter = new Intl.DateTimeFormat("zh-CN", {
  dateStyle: "short",
  timeStyle: "medium",
});

const chineseFormatter = new Intl.DateTimeFormat("zh-CN-u-ca-chinese", {
  dateStyle: "long",
});

const weekdayFormatter = new Intl.DateTimeFormat("zh-CN", {
  weekday: "narrow",
});

const animals = new Map([
  ["子", "鼠"],
  ["丑", "牛"],
  ["寅", "虎"],
  ["卯", "兔"],
  ["辰", "龙"],
  ["巳", "蛇"],
  ["午", "马"],
  ["未", "羊"],
  ["申", "猴"],
  ["酉", "鸡"],
  ["戌", "狗"],
  ["亥", "猪"],
]);

const paddings = new Map([
  ["一", 1],
  ["二", 2],
  ["三", 3],
  ["四", 4],
  ["五", 5],
  ["六", 6],
  ["日", 0],
]);

export function getTime(dateObject = new Date()) {
  const [date, time] = numberFormatter.format(dateObject).split(" ");
  const [, { value: y }, , { value: m }, { value: d }] =
    chineseFormatter.formatToParts(dateObject);
  const week = weekdayFormatter.format(dateObject);
  //[年 月 日 时 分 秒 农历年 月 日 生肖 星期 数字星期]
  return [
    ...date.split("/"),
    ...time.split(":"),
    y,
    m,
    d,
    animals.get(y[1]),
    week,
    paddings.get(week),
  ];
}
